
#-*- coding:UTF-8-*-

__author__='zhaoxp'

'''
refer to http://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/

'''

import types
from collections import Iterable
from inspect import isgeneratorfunction

def calc1(n):
	i=1
	sum=0
	while(i<=n):
		sum=sum+i
		yield sum
		i+=1

def Fab1(max):
	n,a,b=0,0,1
	while n<max:
		print b
		a,b=b,a+b
		n=n+1
	
def Fab2(max):
	n,a,b=0,0,1
	l=[]
	while n<max:
		l.append(b)
		a,b=b,a+b
		n=n+1
	return l

class Fab3(object):
	def __init__(self,max):
		self.max=max
		self.n,self.a,self.b=0,0,1
		
	def __iter__(self):
		return self
		
	def next(self):
		while self.n < self.max:
			r=self.b
			self.a,self.b=self.b,self.a+self.b
			self.n=self.n+1
			return r
		raise StopIteration()

#生成器函数在Python中与迭代器协议的概念联系在一起。简而言之，包含yield语句的函数会被特地编译成生成器。
#当函数被调用时，他们返回一个生成器对象，这个对象支持迭代器接口。函数也许会有个return语句，但它的作用是用来yield产生值的。
def Fab4(max):
	n,a,b=0,0,1
	while n<max:
		yield b
		#print b
		a,b=b,a+b
		n=n+1

def read_file(fpath):
	BLOCK_SIZE=1024
	with open(fpath,'r') as f:
		while True:
			block=f.read(BLOCK_SIZE)
			if block:
				yield block
			else:
				return
		
if __name__=="__main__":
	print '-----start test-----'
	print 'Fab1-->'
	Fab1(5)
	print 'Fab2-->'
	print Fab2(5)
	print 'Fab3-->'
	for n in Fab3(5):
		print n
	print 'Fab4-->'
	for n in Fab4(5):
		print n
	f=Fab4(5)
	try:
		print f.next()
		print f.next()
		print f.next()
		print f.next()
		print f.next()
		print f.next()
	except StopIteration:
		print 'StopIteration....'
	
	print 'isgeneratorfunction(Fab1) = ' + str(isgeneratorfunction(Fab1))
	print 'isgeneratorfunction(Fab2) = ' + str(isgeneratorfunction(Fab2))
	print 'isgeneratorfunction(Fab3) = ' + str(isgeneratorfunction(Fab3))
	print 'isgeneratorfunction(Fab4) = ' + str(isgeneratorfunction(Fab4))
	
	print 'isinstance(Fab4,types.GeneratorType)    = ' + str(isinstance(Fab4,types.GeneratorType))
	print 'isinstance(Fab4(5),types.GeneratorType) = ' + str(isinstance(Fab4(5),types.GeneratorType))
	print 'isinstance(Fab4,Iterable)               = ' + str(isinstance(Fab4,Iterable))
	print 'isinstance(Fab4(5),Iterable)            = ' + str(isinstance(Fab4(5),Iterable))
	
	print '-----end of test----'